<template>
  <j-modal
    centered
    :title="name + '选择'"
    :width="width"
    :visible="visible"
    switchFullscreen
    @ok="handleOk"
    @cancel="close"
    cancelText="关闭">

    <a-row :gutter="18">
      <!-- 查询区域 -->
      <div class="table-page-search-wrapper" v-if="queryParams.length > 0">
        <a-form layout="inline">
          <a-row :gutter="24">
            <div v-for="(item, index) in queryParams" :key="index" :value="item">
              <template v-if="toggleSearchStatus || index < 2">
                <a-col v-if="item.type === 'j-date-scope'" :span="12">
                  <a-form-item :label="item.label">
                    <j-date v-model="queryParam[item.key[0]]" class="query-group-cust" placeholder="请选择开始日期"
                            @pressEnter="searchQuery" v-bind="queryAttrs(item)"/>
                    <span class="query-group-split-cust"></span>
                    <j-date v-model="queryParam[item.key[1]]" class="query-group-cust" placeholder="请选择结束日期"
                            @pressEnter="searchQuery" v-bind="queryAttrs(item)"/>
                  </a-form-item>
                </a-col>
                <a-col v-else-if="item.type === 'j-number-scope'" :span="12">
                  <a-form-item :label="item.label">
                    <j-number v-model="queryParam[item.key[0]]" class="query-group-cust" placeholder="请输入最小数字"
                              @pressEnter="searchQuery" v-bind="queryAttrs(item)"/>
                    <span class="query-group-split-cust"></span>
                    <j-number v-model="queryParam[item.key[1]]" class="query-group-cust" placeholder="请输入最大数字"
                              @pressEnter="searchQuery" v-bind="queryAttrs(item)"/>
                  </a-form-item>
                </a-col>
                <a-col v-else :span="8">
                  <a-form-item :label="item.label" :labelCol="labelCol" :wrapperCol="wrapperCol">
                    <j-category-select v-if="item.type === 'j-category-input'" v-model="queryParam[item.key]"
                                       @pressEnter="searchQuery" v-bind="queryAttrs(item)"/>
                    <j-date v-else-if="item.type === 'j-date'" v-model="queryParam[item.key]"
                            @pressEnter="searchQuery" style="width: 100%" v-bind="queryAttrs(item)"/>
                    <j-dict-select-tag v-model="queryParam[item.key]" v-else-if="item.type === 'j-dict-select-tag'"
                                       v-bind="queryAttrs(item)" @pressEnter="searchQuery"/>
                    <j-select-depart v-model="queryParam[item.key]" v-bind="queryAttrs(item)"
                                     v-else-if="item.type === 'j-select-depart'"/>
                    <j-select-user-by-dep v-model="queryParam[item.key]" v-bind="queryAttrs(item)"
                                          v-else-if="item.type === 'j-select-user-by-dep'"/>
                    <a-input v-else v-model="queryParam[item.key]" v-bind="queryAttrs(item)" @pressEnter="searchQuery"/>
                  </a-form-item>
                </a-col>
              </template>

            </div>

            <a-col :span="8">
                  <span style="float: left;overflow: hidden;" class="table-page-search-submitButtons">
                    <a-button type="primary" @click="searchQuery" icon="search">查询</a-button>
                    <a-button type="primary" @click="searchReset" icon="reload" style="margin-left: 8px">重置</a-button>
                    <a @click="handleToggleSearch" style="margin-left: 8px" v-if="queryParams.length > 2">
                      {{ toggleSearchStatus ? '收起' : '展开' }}
                      <a-icon :type="toggleSearchStatus ? 'up' : 'down'"/>
                    </a>
                  </span>
            </a-col>

          </a-row>
        </a-form>
      </div>

      <a-table
        size="middle"
        bordered
        :rowKey="rowKey"
        :columns="innerColumns"
        :dataSource="dataSource"
        :pagination="ipagination"
        :loading="loading"
        :scroll="{ y: 240 }"
        :rowSelection="{selectedRowKeys, onChange: onSelectChange, type: multiple ? 'checkbox':'radio'}"
        :customRow="customRowFn"
        @change="handleTableChange">
      </a-table>
    </a-row>
  </j-modal>
</template>

<script>
import {getAction} from '@/api/manage'
import Ellipsis from '@/components/Ellipsis'
import {JeecgListMixin} from '@/mixins/JeecgListMixin'
import {cloneObject, pushIfNotExist} from '@/utils/util'
import JCategorySelect from '@/components/jeecg/JCategorySelect'
import JDate from '@/components/jeecg/JDate'
import JSelectDepart from '@/components/jeecgbiz/JSelectDepart'
import JSelectUserByDep from '@/components/jeecgbiz/JSelectUserByDep'

export default {
  name: 'JSelectCustomComponentModal',
  mixins: [JeecgListMixin],
  components: {
    JDate,
    Ellipsis,
    JCategorySelect,
    JSelectDepart,
    JSelectUserByDep,
  },
  props: {
    value: {
      type: Array,
      default: () => []
    },
    visible: {
      type: Boolean,
      default: false
    },
    valueKey: {
      type: String,
      required: true
    },
    queryValueKey: {
      type: String,
      required: false,
      default: ''
    },
    multiple: {
      type: Boolean,
      default: true
    },
    width: {
      type: Number,
      default: 900
    },

    name: {
      type: String,
      default: ''
    },
    listUrl: {
      type: String,
      required: true,
      default: ''
    },
    // 根据 value 获取显示文本的地址，例如存的是 username，可以通过该地址获取到 realname
    valueUrl: {
      type: String,
      default: ''
    },
    displayKey: {
      type: String,
      default: null
    },
    columns: {
      type: Array,
      required: true,
      default: () => []
    },
    queryParams: {
      type: Array,
      required: false,
      default: () => []
    },
    rowKey: {
      type: String,
      default: 'id'
    },
    // 过长裁剪长度，设置为 -1 代表不裁剪
    ellipsisLength: {
      type: Number,
      default: 12
    },
  },
  data() {
    return {
      innerValue: [],
      // 已选择列表
      selectedTable: {
        pagination: false,
        scroll: {y: 240},
        columns: [
          {
            ...this.columns[0],
            width: this.columns[0].widthRight || this.columns[0].width,
          },
          {title: '操作', dataIndex: 'action', align: 'center', width: 60, scopedSlots: {customRender: 'action'},}
        ],
        dataSource: [],
      },
      renderEllipsis: (value) => (<ellipsis length={this.ellipsisLength}>{value}</ellipsis>),
      url: {list: this.listUrl},
      /* 分页参数 */
      ipagination: {
        current: 1,
        pageSize: 5,
        pageSizeOptions: ['5', '10', '20', '30'],
        showTotal: (total, range) => {
          return range[0] + '-' + range[1] + ' 共' + total + '条'
        },
        showQuickJumper: true,
        showSizeChanger: true,
        total: 0
      },
      options: [],
      dataSourceMap: {},
      labelCol: {
        xs: {span: 16},
        sm: {span: 4},
      },
      wrapperCol: {
        xs: {span: 16},
        sm: {span: 12},
      },
    }
  },
  computed: {
    // 表头
    innerColumns() {
      let columns = cloneObject(this.columns)
      columns.forEach(column => {
        // 给所有的列加上过长裁剪
        if (this.ellipsisLength !== -1) {
          column.customRender = (text) => this.renderEllipsis(text)
        }
      })
      return columns
    }
  },
  watch: {
    value: {
      deep: true,
      immediate: true,
      handler(val) {
        this.innerValue = cloneObject(val)
        this.selectedRowKeys = []
        this.valueWatchHandler(val)
        this.queryOptionsByValue(val)
      }
    },
    dataSource: {
      deep: true,
      handler(val) {
        this.emitOptions(val)
        this.valueWatchHandler(this.innerValue)
      }
    },
    selectedRowKeys: {
      immediate: true,
      deep: true,
      handler(val) {
        console.log(val);
        this.selectedTable.dataSource = val.map(key => {
          for (let data of this.dataSource) {
            if (data[this.rowKey] === key) {
              pushIfNotExist(this.innerValue, this.getDataForKey(data, this.valueKey))
              return data
            }
          }
          for (let data of this.selectedTable.dataSource) {
            if (data[this.rowKey] === key) {
              pushIfNotExist(this.innerValue, this.getDataForKey(data, this.valueKey))
              return data
            }
          }
          console.warn('未找到选择的行信息，key：' + key)
          return {}
        })
      },
    }
  },
  methods: {

    /** 关闭弹窗 */
    close() {
      this.$emit('update:visible', false)
    },

    valueWatchHandler(val) {
      val.forEach(item => {
        this.dataSource.concat(this.selectedTable.dataSource).forEach(data => {
          if (this.getDataForKey(data, this.valueKey) === item) {
            pushIfNotExist(this.selectedRowKeys, data[this.rowKey])
          }
        })
      })
    },

    queryOptionsByValue(value) {
      if (!value || value.length === 0) {
        return
      }
      // 判断options是否存在value，如果已存在数据就不再请求后台了
      let notExist = false
      for (let val of value) {
        let find = false
        for (let option of this.options) {
          if (val === option.value) {
            find = true
            break
          }
        }
        if (!find) {
          notExist = true
          break
        }
      }
      if (!notExist) return
      let url = this.valueUrl || this.listUrl
      if (url.indexOf("?") > -1) {
        url = url.substring(0, url.indexOf("?"))
      }
      getAction(url, {
        // 这里最后加一个 , 的原因是因为无论如何都要使用 in 查询，防止后台进行了模糊匹配，导致查询结果不准确
        [this.queryValueKey || this.valueKey]: value.join(',') + ',',
        pageNo: 1,
        pageSize: value.length
      }).then((res) => {
        if (res.success) {
          let dataSource = res.result
          if (!(dataSource instanceof Array)) {
            dataSource = res.result.records
          }
          this.emitOptions(dataSource, (data) => {
            pushIfNotExist(this.innerValue, this.getDataForKey(data, this.valueKey))
            pushIfNotExist(this.selectedRowKeys, data[this.rowKey])
            pushIfNotExist(this.selectedTable.dataSource, data, data[this.rowKey])
          })
        }
      })
    },

    emitOptions(dataSource, callback) {
      console.log(dataSource)
      dataSource.forEach(data => {
        let key = this.getDataForKey(data, this.valueKey)
        this.dataSourceMap[key] = data
        pushIfNotExist(this.options, {
          label: this.getDataForKey(data, this.displayKey || this.valueKey),
          value: key
        }, 'value')
        typeof callback === 'function' ? callback(data) : ''
      })
      this.$emit('options', this.options, this.dataSourceMap)
    },

    /** 完成选择 */
    handleOk() {
      let value = this.selectedTable.dataSource.map(data => this.getDataForKey(data, this.valueKey))
      this.$emit('input', value)
      this.close()
    },

    /** 删除已选择的 */
    handleDeleteSelected(record, index) {
      this.selectedRowKeys.splice(this.selectedRowKeys.indexOf(record[this.rowKey]), 1)
      this.selectedTable.dataSource.splice(index, 1)
    },

    customRowFn(record) {
      return {
        on: {
          click: () => {
            let key = record[this.rowKey]
            if (!this.multiple) {
              this.selectedRowKeys = [key]
              this.selectedTable.dataSource = [record]
            } else {
              let index = this.selectedRowKeys.indexOf(key)
              if (index === -1) {
                this.selectedRowKeys.push(key)
                this.selectedTable.dataSource.push(record)
              } else {
                this.handleDeleteSelected(record, index)
              }
            }
          }
        }
      }
    },
    getDataForKey(data, key) {
      let keys = key.split('.')
      let value = data;
      for (let i = 0; i < keys.length; i++) {
        if (value) {
          value = value[keys[i]]
        }
      }
      return value;
    },
    queryAttrs(item) {
      return Object.assign({placeholder: '请输入' + item.label}, item.options ? item.options : {})
    },
  }
}
</script>
<style lang="less" scoped>
</style>